/**
 * useImperativeHandle
 *    作用：让组件可以自定义对外的暴露，父组件通过 ref 可以获取到该自定义对外的暴露
 *    PS: 该 hook 需要配合 forwardRef 一起使用才行
 *    语法：
 *      useImperativeHandle(ref, init, deps)
 *      1. ref - 转发收到的ref对象
 *      2. init - 是一个函数，该函数的返回值作为对外的暴露，一般会返回一个大对象出去
 *      3. deps - 依赖项数组，该项发生变化，会引起 init 的重新执行
 *
 * 回顾一下：
 *    1. ref 标记能否直接标记一个函数组件？
 *      不可以，会直接报错，函数组件是没有实例的。要操作的话，需要让函数组件做 ref 转发
 */

import { useRef, forwardRef, useImperativeHandle, useState } from "react";
import { Button, Space } from "antd";

const Hello = forwardRef((props, ref) => {
  const [value, setValue] = useState("");

  // 使用
  useImperativeHandle(
    ref,
    () => {
      console.log("init", value);
      return {
        getFieldsValue() {},
        setFiledsValue() {},
        getValue() {
          return value;
        },
      };
    },
    [value]
  );

  return (
    <div>
      <p>Hello - {value}</p>
      <input
        type="text"
        value={value}
        onChange={(event) => setValue(event.target.value)}
      />
    </div>
  );
});

export default function App() {
  const helloRef = useRef(null);

  function onClickOne() {
    console.log(helloRef.current);
  }

  function onClickTwo() {
    const msg = helloRef.current.getValue();
    console.log("msg", msg);
  }

  return (
    <div>
      <h1>useImperativeHandle</h1>
      <Space>
        <Button onClick={onClickOne}>获取 Hello 组件的内容</Button>
        <Button onClick={onClickTwo}>获取 Hello 组件内 value 值</Button>
      </Space>
      <hr />
      <Hello ref={helloRef} />
    </div>
  );
}
